using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class UIN_PetWarehouse : UIBaseNode
    {
        #region Template Generate,don't modify
        protected class UIB_UIN_PetWarehouse
        {
            #region ObjectBinding Generate 
            public IQIGame.Onigao.Framework.ExText textNum { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textLimit { protected set; get; }
            public UnityEngine.UI.ExLoopVerticalScrollRect loopVerticalScrollRect { protected set; get; }
            public UnityEngine.GameObject emptyScroll { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonScreen { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnFilterClear { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonSort { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textNum", out var __tbv0);
                this.textNum = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textLimit", out var __tbv1);
                this.textLimit = __tbv1;
                __binding.TryGetVariableValue<UnityEngine.UI.ExLoopVerticalScrollRect>("loopVerticalScrollRect", out var __tbv2);
                this.loopVerticalScrollRect = __tbv2;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("emptyScroll", out var __tbv3);
                this.emptyScroll = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonScreen", out var __tbv4);
                this.buttonScreen = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnFilterClear", out var __tbv5);
                this.btnFilterClear = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonSort", out var __tbv6);
                this.buttonSort = __tbv6;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields
        private LoopScrollAdapter<UIN_CommonPet> pets;

        private System.Action<Pet> callOnWarehoseState;
        private long currPetId = -1;
        private List<Pet> dataList = new(16);
        private List<Pet> dataCurrList = new(16);
        private int indexSelected = -1;

        private PetFilter filter = PetFilter.Default;
        private PetSort sort = PetSort.Default;

        #endregion fields

        #region properties

        protected UIB_UIN_PetWarehouse ui { get; set; }
        protected UIMsgDispatcher uiMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;

        #endregion properties

        protected override void BeforeInit()
        {
            ui = new UIB_UIN_PetWarehouse();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {
            this.pets = this.InitLoopScroll<UIN_CommonPet>(this.ui.loopVerticalScrollRect, this.OnPetChanged);
            this.pets.InitUnitSelected(UnitSelectType.ByExButton, this.OnPetSelected);
        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {

        }

        /// <summary>
        /// 添加UGUI侦听
        /// </summary>
        protected override void AddUGUIListener()
        {
            this.ui.btnFilterClear.onClick.AddListener(this.OnClickBtnFilterClear);
            this.ui.buttonScreen.onClick.AddListener(this.OnClickBtnFilter);
            this.ui.buttonSort.onClick.AddListener(this.OnClickBtnSort);
        }

        /// <summary>
        /// 添加全局侦听（MsgDispatcher）
        /// </summary>
        protected override void AddMsgListeners()
        {
            this.uiMsgDispatcher.AddListener<PetFilter>(MsgEventType.PetFilter, this.OnMsgFilter);
            this.uiMsgDispatcher.AddListener<PetSort>(MsgEventType.PetSort, this.OnMsgSort);
        }

        protected override void OnDispose()
        {
            this.ClearData();
        }

        #region methonds

        public void Show(System.Action<Pet> funcWarehouseState, long currPetId = -1)
        {
            this.SetData(funcWarehouseState, currPetId);
            this.Show();
            this.ShowWarehouse();
        }

        private void SetData(System.Action<Pet> funcWarehouseState, long currPetId)
        {
            this.callOnWarehoseState = funcWarehouseState;
            this.currPetId = currPetId;
            this.InitDataList();
        }

        private void InitDataList()
        {
            this.dataList.Clear();
            var list = GameDataCenter.PlayerData.pet.GetPetList();
            this.dataList.AddRange(list);
        }

        private void ClearData()
        {
            this.callOnWarehoseState = null;
            this.currPetId = -1;
            this.dataList?.Clear();
            this.dataCurrList?.Clear();
        }

        private void ExcuteCall(Pet pet = null)
        {
            this.callOnWarehoseState?.Invoke(pet);
        }

        private void ShowWarehouse()
        {
            this.FitlerAndSortDatalist();

            this.ShowCapacity();
            this.ShowBtnFilterState();
            this.ShowListState();
        }

        private void FitlerAndSortDatalist()
        {
            this.FitlerDatalist();
            this.SortDataList();
        }

        private void FitlerDatalist()
        {
            this.dataCurrList.Clear();
            this.dataCurrList = PetModule.Instance.LeachList(this.dataList, this.filter, this.dataCurrList);
        }

        private void SortDataList()
        {
            PetModule.Instance.ReorderList(this.dataCurrList, this.sort);
        }

        private void ShowCapacity()
        {
            int cntHas = this.dataCurrList.Count;
            int cntMax = GameDataCenter.PlayerData.pet.bagCapacity;
            this.ui.textNum.text = cntHas.ToString();
            this.ui.textLimit.text = "/" + cntMax;
        }

        private void ShowBtnFilterState()
        {
            bool isActive = this.filter != PetFilter.Default;
            this.ui.btnFilterClear.SetActive(isActive);
        }

        private void ShowListState()
        {
            int cnt = this.dataCurrList.Count;
            int index = this.GetListSelectedIndex();
            this.ShowPetList(cnt, index);
            bool isEmpty = cnt == 0;
            this.ShowEmptyList(isEmpty);
            if (isEmpty)
            {
                this.ExcuteCall();
            }
        }

        private int GetListSelectedIndex()
        {
            int index = this.GetListSelectedIndexByCurrPetId();
            if (index == -1)
            {
                index = Math.Min(this.indexSelected, this.dataCurrList.Count - 1);
            }
            return index == -1 ? 0 : index;
        }

        private int GetListSelectedIndexByCurrPetId()
        {
            int index = -1;
            if (this.currPetId > 0)
            {
                for (int i = 0, cnt = this.dataCurrList.Count; i < cnt; i++)
                {
                    var pet = this.dataCurrList[i];
                    if (pet.id == this.currPetId)
                    {
                        index = i;
                        break;
                    }
                }
            }
            return index;
        }

        private void ShowPetList(int countList, int indexSelected)
        {
            this.pets.RefillCellsAndSelected(countList, indexSelected);
        }

        private void OnPetChanged(UIN_CommonPet item, int index)
        {
            var pet = this.dataCurrList[index];
            item.Show(pet);
            item.SetSelected(this.indexSelected == index);
        }

        private void OnPetSelected(int index, UIN_CommonPet item)
        {
            UIN_CommonPet last = this.pets.GetTEntity(this.indexSelected);
            last?.SetSelected(false);

            this.indexSelected = index;
            Pet pet = null;
            if (item != null)
            {
                item.SetSelected(true);
                pet = this.dataCurrList[index];
            }
            this.ExcuteCall(pet);
        }

        private void ShowEmptyList(bool isEmptyList)
        {
            this.ui.emptyScroll.SetActive(isEmptyList);
        }

        private void OnClickBtnFilter()
        {
            this.OpenUI<UIPetListScreen>(UD_PetListScreen.Create(this.filter));
        }

        private void OnClickBtnFilterClear()
        {
            this.filter = PetFilter.Default;
            this.RefreshWearhouse();
        }

        private void RefreshWearhouse()
        {
            this.indexSelected = -1;
            this.ShowWarehouse();
        }

        private void OnMsgFilter(PetFilter filter)
        {
            if (this.filter == filter)
                return;
            this.filter.Sync(filter);
            this.RefreshWearhouse();
        }

        private void OnClickBtnSort()
        {
            this.OpenUI<UIPetListSort>(UD_PetListSort.Create(this.sort));
        }

        private void OnMsgSort(PetSort sort)
        {
            if (this.sort == sort)
                return;
            this.sort.Sync(sort);
            this.SortDataList();
            this.ShowListState();
        }

        #endregion methonds
    }
}
